package m.store.task;

import m.common.action.Action;
import m.common.model.util.ModelUpdate;
import m.common.model.util.QueryCondition;
import m.store.model.*;
import m.system.db.TransactionManager;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.LockSupport;

public class StoreGoodsSupport implements Runnable {
    private StoreGoodsSupport(){}
    private static boolean isRun=true;
    static Thread th;
    static final List<String> ls=new ArrayList<>();
    static String current=null;

    @Override
    public void run() {
        while (true){
            if(ls.isEmpty()){
                TransactionManager.closeConnection();
                LockSupport.park();
                TransactionManager.initConnection();
            }
            if(!isRun) break;
            if(!ls.isEmpty()){
                current=ls.remove(0);
                execute(current);
                current=null;
            }
        }
    }
    private void execute(String oid){
        try {
            if(ls.size()<10) Thread.sleep(100L);
            //更新商品冗余信息
            ModelUpdate.init(StoreGoods.class)
            .set("stockNum", GoodsStockRecord.class, "ifnull(sum(#{stockNum}),0)",
                QueryCondition.and(
                    QueryCondition.eq("goods.oid", oid),
                    QueryCondition.in("stock.status", OrderModel.Status_Done)
                )
            )
            .set("stockAmount", GoodsStockRecord.class, "ifnull(sum(#{stockAmount}),0)",
                QueryCondition.and(
                    QueryCondition.eq("goods.oid", oid),
                    QueryCondition.in("stock.status", OrderModel.Status_Done)
                )
            )
            .set("saleNum", GoodsOutRecord.class, "ifnull(sum(#{num}),0)",
                QueryCondition.and(
                    QueryCondition.eq("goods.oid", oid),
                    QueryCondition.in("sale.status", OrderModel.Status_Done)
                )
            )
            .set("saleAmount", GoodsOutRecord.class, "ifnull(sum(#{saleAmount}),0)",
                QueryCondition.and(
                    QueryCondition.eq("goods.oid", oid),
                    QueryCondition.in("sale.status", OrderModel.Status_Done)
                )
            )
            .set("surplusNum", GoodsStockRecord.class, "ifnull(sum(#{surplusNum}),0)",
                QueryCondition.and(
                    QueryCondition.eq("goods.oid", oid),
                    QueryCondition.in("stock.status", OrderModel.Status_Done)
                )
            )
            .set("surplusAmount", GoodsStockRecord.class, "ifnull(sum(#{surplusAmount}),0)",
                QueryCondition.and(
                    QueryCondition.eq("goods.oid", oid),
                    QueryCondition.in("stock.status", OrderModel.Status_Done)
                )
            )
            .setExp("surplusPrice", "ifnull(round(#{surplusAmount}/#{surplusNum},2),0)")
            .set("gainAmount", GoodsOutRecord.class, "ifnull(sum(#{gainAmount}),0)",
                QueryCondition.and(
                    QueryCondition.eq("goods.oid", oid),
                    QueryCondition.in("sale.status", OrderModel.Status_Done)
                )
            )
            .execute(oid);
        } catch (Exception e) {
            Action.directLog("定时任务","更新商品冗余信息失败",this.getClass().getName(),oid,e);
        }
    }
    /**
     * 添加要更新的商品oid
     */
    public static void add(String goods_oid){
        if(!ls.contains(goods_oid))
            ls.add(goods_oid);
    }

    /**
     * 开始更新
     */
    public static void start(){
        if(null==th){
            th=new Thread(new StoreGoodsSupport());
            th.start();
        }else{
            LockSupport.unpark(th);
        }
    }

    public static void close(){
        isRun=false;
        LockSupport.unpark(th);
    }

    /**
     * 指定参数完成后跳出方法
     */
    public static void doneHandler(String... goodsOids) throws InterruptedException {
        doneHandler(true,goodsOids);
    }
    private static void doneHandler(boolean runRecord,String... goodsOids) throws InterruptedException {
        if(runRecord) {
            GoodsStockRecordSupport.doneHandler(goodsOids);
            GoodsOutRecordSupport.doneHandler(goodsOids);
        }
        for(String oid : goodsOids){
            if(oid.equals(current)){
                Thread.sleep(30L);
                doneHandler(false,oid);
            }else {
                if (ls.contains(oid)) {
                    Thread.sleep(30L);
                    doneHandler(false, oid);
                }
            }
        }
    }
}
